﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Windows;
using System.Windows.Controls;
using System.Net;
using System.Web;
using System.ComponentModel;
using System.Diagnostics;

namespace XMM.Objects
{
    public class UpdateDescriptor
    {
        private string _LatestVersion;
        public string LatestVersion { get { return _LatestVersion; } }

        private DateTime _DistributionDate;
        public DateTime DistributionDate { get { return _DistributionDate; } }

        private string _Description;
        public string Description { get { return _Description; } }

        private string _Path;
        public string Path { get { return _Path; } }

        private string DescriptorFile { get; set; }

        private Settings LocalConfig { get; set; }

        private bool Interactive = false;

        /// <summary>
        /// Initiate new Update-Descriptor.
        /// </summary>
        /// <remarks>Download 'updates.xml', parse data and inform user.</remarks>
        public UpdateDescriptor()
        {
            LocalConfig = new Settings();

            downloadDescriptor();
        }

        public UpdateDescriptor(bool bInteractive)
        {
            Interactive = bInteractive;

            LocalConfig = new Settings();

            downloadDescriptor();
        }

        /// <summary>
        /// Download current description-file.
        /// </summary>
        /// <returns>[true] if 'updates.xml' was successfully downloaded.
        /// [false] if 'updates.xml' was not successfully downloaded or saved.</returns>
        private bool downloadDescriptor()
        {
            // Delete old descriptor first.
            if (System.IO.File.Exists(Tools.getInstallationPath() + "updates.xml"))
            {
                try
                {
                    System.IO.File.Delete(Tools.getInstallationPath() + "updates.xml");
                }
                catch (System.IO.IOException ex)
                {
                    return false;
                }
            }

            try
            {
                WebClient webClient = new WebClient();
                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadCompleted);
                //webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
                webClient.DownloadFileAsync(new Uri("http://www.paco-lechner.at/xmm/updates.xml"), Tools.getInstallationPath() + "updates.xml");

                return true;
            }
            catch (TimeoutException ex)
            {
                if(Interactive)
                    System.Windows.MessageBox.Show("Der Update-Service ist derzeit nicht erreichbar! Bitte versuchen Sie es später erneut!", "Update-Service offline", MessageBoxButton.OK, MessageBoxImage.Information);
                return false;
            }

            return false;
        }

        private void DownloadCompleted(object sender, AsyncCompletedEventArgs e)
        {
            //MessageBox.Show("Download completed!");
            if (System.IO.File.Exists(Tools.getInstallationPath() + "updates.xml"))
            {
                Settings oSettings = new Settings();
                oSettings.LastUpdate = DateTime.Now;
                oSettings.Save();

                DescriptorFile = Tools.getInstallationPath() + "updates.xml";

                Load();

                if (CheckNewerVersion())
                {
                    string sMessage = "Neue Version verfügbar!" + Environment.NewLine + Environment.NewLine;
                    sMessage += "Installiert:     " + Tools.getVersion() + Environment.NewLine;
                    sMessage += "Neueste Version: " + LatestVersion + Environment.NewLine + Environment.NewLine;
                    if (Description != String.Empty)
                    {
                        sMessage += "Änderungen:" + Environment.NewLine;
                        sMessage += Description + Environment.NewLine + Environment.NewLine;
                    }
                    sMessage += "Möchten Sie jetzt updaten?";

                    if (System.Windows.MessageBox.Show(sMessage, "Update verfügbar", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                    {
                        downloadUpdate();
                    }
                }
                else
                {
                    if(Interactive)
                        System.Windows.MessageBox.Show("XMM ist auf dem neuesten Stand!", "Suche nach Updates abgeschlossen", MessageBoxButton.OK, MessageBoxImage.Information);
                }
            }
            else
            {
                if(Interactive)
                    System.Windows.MessageBox.Show("Unbekannter Fehler beim Download der Update-Informationen! Bitte versuchen Sie es später erneut!", "Fehler beim Abrufen von Update-Informationen", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void DownloadUpdateCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (System.IO.File.Exists(Tools.getInstallationPath() + "XMM-Installer-" + LatestVersion + ".exe"))
            {
                ProcessStartInfo oStartInfo = new ProcessStartInfo(Tools.getInstallationPath() + "XMM-Installer-" + LatestVersion + ".exe");
                oStartInfo.UseShellExecute = true;
                oStartInfo.ErrorDialog = true;
                oStartInfo.CreateNoWindow = false;
                oStartInfo.RedirectStandardOutput = false;
                oStartInfo.RedirectStandardInput = false;

                Process pUpdateProcess = System.Diagnostics.Process.Start(oStartInfo);
                Environment.Exit(0);
            }
        }

        private void downloadUpdate()
        {
            try
            {
                WebClient webClient = new WebClient();
                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadUpdateCompleted);
                //webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
                webClient.DownloadFileAsync(new Uri(Path), Tools.getInstallationPath() + "XMM-Installer-" + LatestVersion + ".exe");
            }
            catch (TimeoutException ex)
            {
                System.Windows.MessageBox.Show("Der Update-Service ist derzeit nicht erreichbar! Bitte versuchen Sie es später erneut!", "Update-Service offline", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        private bool CheckNewerVersion()
        {
            string sCurrentVersion = Tools.getVersion();

            if (LatestVersion != sCurrentVersion)
            {
                return true;
            }

            return false;
        }

        /// <summary>
        /// Load Data from downloaded 'updates.xml'.
        /// </summary>
        /// <returns>[true] if data was loaded successfully.
        /// [false] if config-file is corrupted.</returns>
        private bool Load()
        {
            if (System.IO.File.Exists(DescriptorFile))
            {
                XmlDocument xdDescriptorFile = new XmlDocument();
                try
                {
                    xdDescriptorFile = new XmlDocument();
                    xdDescriptorFile.Load(DescriptorFile);

                    XmlElement xeDocumentNode = xdDescriptorFile.DocumentElement;
                    XmlNode xnLatestVersion = xeDocumentNode.SelectSingleNode("//LatestVersion");
                    XmlNode xnDistributionDate = xeDocumentNode.SelectSingleNode("//DistributionDate");
                    XmlNode xnDescription = xeDocumentNode.SelectSingleNode("//Description");
                    XmlNode xnPath = xeDocumentNode.SelectSingleNode("//Path");

                    _LatestVersion = xnLatestVersion.InnerText;
                    _DistributionDate = DateTime.Parse(xnDistributionDate.InnerText);
                    _Description = xnDescription.InnerText;
                    _Path = xnPath.InnerText;

                    return true;
                }
                catch (XmlException ex)
                {
                    if(Interactive)
                        MessageBox.Show("Fehler beim Verarbeiten der Update-Informationen:" + Environment.NewLine + Environment.NewLine + xdDescriptorFile.InnerXml + Environment.NewLine + Environment.NewLine + ex.Message, "Fehlerhafte Update-Informationen!", MessageBoxButton.OK, MessageBoxImage.Warning);
                }

            }

            return false;
        }

    }
}
